package com.wz.jaav.rtda.heap;

import com.wz.jaav.classreader.ClassLoader;
import com.wz.jaav.classreader.classFile.ConstantPool;
import com.wz.jaav.classreader.classFile.FieldInfo;
import com.wz.jaav.classreader.classFile.MethodInfo;
import com.wz.jaav.classreader.classFile.file.ClassFile;
import com.wz.jaav.rtda.Slot;
import com.wz.jaav.util.ByteArrayConveter;

public class Clazz {
    private ConstantPool constantPool;
    private int accessFlags;
    private String name;
    private String superClazzName;
    private String[] interfaceNames;
    private FieldInfo[] fieldInfos;
    private MethodInfo[] methodInfos;
    private ClassLoader loader;
    private Clazz superClass;
    private Clazz[] interfaces;
    private byte instanceSlotCount;
    private byte staticSlotCount;
    private Slot staticVars;

    public Clazz newClass(ClassFile classFile){
        this.setConstantPool(classFile.getConstantPool());
        this.setAccessFlags(ByteArrayConveter.getInt(classFile.getAccessFlags().getFlag(), 0));
//        this.setSuperClass(classFile.getSuperClass().getSuperClass());
//        this.setInterfaceNames(classFile.getInterfaces());
        this.setFieldInfos(classFile.getFieldInfoPool().getInfos());
        this.setMethodInfos(classFile.getMethodInfoPool().getInfos());
        return this;
    }

    public boolean isPublic(){
        return (this.accessFlags & AccessFlagEnum.ACC_PUBLIC.getSign()) != 0;
    }

    public boolean isFinal(){
        return (this.accessFlags & AccessFlagEnum.ACC_FINAL.getSign()) != 0;
    }

    public boolean isSuper(){
        return (this.accessFlags & AccessFlagEnum.ACC_SUPER.getSign()) != 0;
    }

    public boolean isInterface(){
        return (this.accessFlags & AccessFlagEnum.ACC_INTERFACE.getSign()) != 0;
    }

    public boolean isAbstract(){
        return (this.accessFlags & AccessFlagEnum.ACC_ABSTRACT.getSign()) != 0;
    }

    public boolean isSynthetic(){
        return (this.accessFlags & AccessFlagEnum.ACC_SYNTHETIC.getSign()) != 0;
    }

    public boolean isAnnotation(){
        return (this.accessFlags & AccessFlagEnum.ACC_ANNOTATION.getSign()) != 0;
    }

    public boolean isEnum(){
        return (this.accessFlags & AccessFlagEnum.ACC_ENUM.getSign()) != 0;
    }

    public int getAccessFlags() {
        return accessFlags;
    }

    public void setAccessFlags(int accessFlags) {
        this.accessFlags = accessFlags;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSuperClazzName() {
        return superClazzName;
    }

    public void setSuperClazzName(String superClazzName) {
        this.superClazzName = superClazzName;
    }

    public String[] getInterfaceNames() {
        return interfaceNames;
    }

    public void setInterfaceNames(String[] interfaceNames) {
        this.interfaceNames = interfaceNames;
    }

    public ConstantPool getConstantPool() {
        return constantPool;
    }

    public void setConstantPool(ConstantPool constantPool) {
        this.constantPool = constantPool;
    }

    public FieldInfo[] getFieldInfos() {
        return fieldInfos;
    }

    public void setFieldInfos(FieldInfo[] fieldInfos) {
        this.fieldInfos = fieldInfos;
    }

    public MethodInfo[] getMethodInfos() {
        return methodInfos;
    }

    public void setMethodInfos(MethodInfo[] methodInfos) {
        this.methodInfos = methodInfos;
    }

    public ClassLoader getLoader() {
        return loader;
    }

    public void setLoader(ClassLoader loader) {
        this.loader = loader;
    }

    public Clazz getSuperClass() {
        return superClass;
    }

    public void setSuperClass(Clazz superClass) {
        this.superClass = superClass;
    }

    public Clazz[] getInterfaces() {
        return interfaces;
    }

    public void setInterfaces(Clazz[] interfaces) {
        this.interfaces = interfaces;
    }

    public byte getInstanceSlotCount() {
        return instanceSlotCount;
    }

    public void setInstanceSlotCount(byte instanceSlotCount) {
        this.instanceSlotCount = instanceSlotCount;
    }

    public byte getStaticSlotCount() {
        return staticSlotCount;
    }

    public void setStaticSlotCount(byte staticSlotCount) {
        this.staticSlotCount = staticSlotCount;
    }

    public Slot getStaticVars() {
        return staticVars;
    }

    public void setStaticVars(Slot staticVars) {
        this.staticVars = staticVars;
    }
}